; ====================================================================================
; klib.asm
; ====================================================================================


%include "sconst.inc"

; 导入全局变量
extern	disp_pos

[SECTION .text]
global	disp_str		; 导出函数
global	disp_color_str
global	out_byte
global	in_byte
global	disable_irq
global	enable_irq
global	disable_int
global	enable_int

; ------------------------------------------------------------------------
; void disp_str(char * info);
; 显示一个字符串
; ------------------------------------------------------------------------
disp_str:
	push	ebp
	mov	ebp, esp

	push 	esi		; eax, ecx, edx 是调用方保护
	push	edi		; ebx, edi, esi 是被调用方保护
	push	ebx

	mov	esi, [ebp + 8]	; pszInfo
	mov	edi, [disp_pos]
	mov	ah, 0Fh
.1:
	lodsb
	test	al, al
	jz	.2
	cmp	al, 0Ah	; 是回车吗?
	jnz	.3
	push	eax
	mov	eax, edi
	mov	bl, 160
	div	bl
	and	eax, 0FFh
	inc	eax
	mov	bl, 160
	mul	bl
	mov	edi, eax
	pop	eax
	jmp	.1
.3:
	mov	[gs:edi], ax
	add	edi, 2
	jmp	.1

.2:
	mov	[disp_pos], edi

	pop	ebx
	pop	edi
	pop	esi
	
	pop	ebp
	ret

; ------------------------------------------------------------------------
; void disp_color_str(char * info, int color);
; 显示一个字符串，并指定颜色
; ------------------------------------------------------------------------
disp_color_str:
	push	ebp
	mov	ebp, esp

	push 	esi		; eax, ecx, edx 是调用方保护
	push	edi		; ebx, edi, esi 是被调用方保护
	push	ebx

	mov	esi, [ebp + 8]	; pszInfo
	mov	edi, [disp_pos]
	mov	ah, [ebp + 12]	; color
.1:
	lodsb
	test	al, al
	jz	.2
	cmp	al, 0Ah	; 是回车吗?
	jnz	.3
	push	eax
	mov	eax, edi
	mov	bl, 160
	div	bl
	and	eax, 0FFh
	inc	eax
	mov	bl, 160
	mul	bl
	mov	edi, eax
	pop	eax
	jmp	.1
.3:
	mov	[gs:edi], ax
	add	edi, 2
	jmp	.1

.2:
	mov	[disp_pos], edi

	pop	ebx
	pop	edi
	pop	esi
	
	pop	ebp
	ret
	
; ------------------------------------------------------------------------
; void out_byte(t_port port, t_8 value);
; 功能：往端口写入字节
; ------------------------------------------------------------------------
out_byte:
	mov	edx, [esp + 4]		; port
	mov	al, [esp + 4 + 4]	; value
	out	dx, al

	nop		; 一点延迟
	nop
	ret

; ------------------------------------------------------------------------
; t_8 in_byte(t_port port);
; 功能：从端口读字节
; ------------------------------------------------------------------------
in_byte:
	mov	edx, [esp + 4]		; port
	xor	eax, eax
	in	al, dx

	nop		; 一点延迟
	nop
	ret

; ------------------------------------------------------------------------
; void disable_irq(int irq);
; 功能：禁止对应中断
; ------------------------------------------------------------------------
disable_irq:
	mov	ecx, [esp + 4]		; irq
	pushf			; 标志寄存器压栈
	cli 
	mov ah, 1
	rol ah, cl		; ah = (1 << (irq % 8))
	cmp	cl, 8
	jae	disable_8	; 无符号数大于等于跳转 jae  disable irq >= 8 at the slave 8259
disable_0:
	in	al, INT_M_CTLMASK
	test	al, ah
	jnz	dis_already			; 已经禁止
	or	al, ah
	out	INT_M_CTLMASK, al	; set bit at master 8259
	popf
	mov	eax, 1				; 这个函数禁止成功 返回值
	ret
disable_8:
	in	al, INT_S_CTLMASK
	test	al, ah
	jnz	dis_already			; 已经禁止
	or	al, ah
	out	INT_S_CTLMASK, al	; set bit at slave 8259
	popf
	mov	eax, 1				; 这个函数禁止成功 返回值
	ret
dis_already:
	popf
	xor	eax, eax			; 之前就是禁止的 返回值
	ret

; ------------------------------------------------------------------------
; void enable_irq(int irq);
; 功能：启用对应中断
; ------------------------------------------------------------------------
enable_irq:
        mov	ecx, [esp + 4]		; irq
        pushf
        cli
        mov	ah, ~1
        rol	ah, cl			; ah = ~(1 << (irq % 8)) 循环左移
        cmp	cl, 8
        jae	enable_8		; enable irq >= 8 at the slave 8259
enable_0:
        in	al, INT_M_CTLMASK
        and	al, ah
        out	INT_M_CTLMASK, al	; clear bit at master 8259
        popf
        ret
enable_8:
        in	al, INT_S_CTLMASK
        and	al, ah
        out	INT_S_CTLMASK, al	; clear bit at slave 8259
        popf
        ret

; ------------------------------------------------------------------------
; void disable_int();
; 功能：启用中断
; ------------------------------------------------------------------------
disable_int:
	cli
	ret

; ------------------------------------------------------------------------
; void enable_int();
; 功能：禁用中断
; ------------------------------------------------------------------------
enable_int:
	sti
	ret